let params = {
  images: {},
  webUrl: ''
}

/**
 * 初始化导出参数
 */
function initParams() {
  params = {
    images: {},
    webUrl: ''
  }
}

// 保存图片
let imageList = {}

// 设置参数
let setup = {
  dirRootPath: '',
  root: "",
  subDirs: []
}

/**
 * 初始化加载设置参数
 */
function initSetup() {
  axios({
    url: "http://127.0.0.1:3000/getSetup",
    method: "get"
  }).then(result => {
    console.log(result);
    if (result.data.code === 200) {
      setup = result.data.data;
      if (!setup.subDirs) setup.subDirs = [];

      for (let i = 0; i < setup.subDirs.length; i++) {
        $(".sub__dirs").append($(getSubDirItem(i)))
      }

      renderImageGroup();
      update()
    }
  }).catch((err) => {
    console.log(err);
  })
}

// 导出状态
let isLoading = false;

window.onload = function () {
  // 初始化导出图片参数
  initParams();
  // 初始化设置项
  initSetup();
  // // 获取当前页面的图片
  // getImages();

  // 获取图片
  $("#popup__get__img__button").on('click', getImages)
  // 导出
  $("#popup__export__button").on('click', exportImages)
  // 监听表单输入
  $('.setup__form form').on('input', inputHandle)
  // 保存设置内容
  $('.save__button').on('click', saveSetup)
  // 取消保存
  $('.cancel__button').on('click', toggleSettingPanpelStatus)
  // 关闭设置弹框
  $('.setting__panpel__close').on('click', toggleSettingPanpelStatus)
  // 弹出设置框
  $('.popup__setting__icon').on('click', toggleSettingPanpelStatus)
  // 添加子目录
  $(".add__dirs").on("click", addSubDirs)
  // 删除子目录
  $(".sub__dirs").on('click', removeSubDirHandle)
}

function removeSubDirHandle(event) {
  let el = parentNode(event.target, 'remove__sub__dir')
    
  if (el) {
    const index = el.dataset.index
    setup.subDirs.splice(index, 1)
    $(".sub__dir__item").eq(index).remove()
    update()
  };
}

function exportImages(event) {
  if (isLoading) return;
  event.target.classList.add("popup__export__loading")
  isLoading = true;

  let data = deepClone(params)

  const keys = Object.keys(data.images)

  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    data.images[key] = data.images[key].filter(item => item.isSelected).map(item => item.src);
  }

  axios({
    url: 'http://127.0.0.1:3000/images',
    method: "post",
    data
  }).then(result => {
    console.log('result', result);
    event.target.classList.remove("popup__export__loading")
  }).catch(err => {
    console.log('err', err);
    event.target.classList.remove("popup__export__loading")
  }).finally(() => isLoading = false);
}

function inputHandle(event) {
  const name = event.target.getAttribute('name')
  if (name === 'subDirs') {
    const index = event.target.dataset.index
    setup[name][index].dirname = event.target.value
  } else if (name === 'xpath') {
    const index = event.target.dataset.index
    setup.subDirs[index].xpath = event.target.value
  } else {
    setup[name] = event.target.value
  }
  update()
}

function addSubDirs(event) {
  setup.subDirs.push({
    dirname: '',
    xpath: ''
  })
  
  const index = setup.subDirs.length - 1

  $(".sub__dirs").append($(getSubDirItem(index)))

  update()

  const sub__dirs = document.querySelector(".sub__dirs")
  sub__dirs.scrollTo({
    top: sub__dirs.scrollHeight,
    behavior: "smooth"
  })
}

function getSubDirItem(index) {
  return `
    <div class="sub__dir__item">
      <div class="dir__wrapper">
        <span class="setup__label">目录</span>
        <div class="setup__input__wrapper">
          <input type="text" class="form__input" data-index="${index}" placeholder="目录名称" name="subDirs">
          <span class="path_preview">
            <span>预览：</span>
            <span class="dirpath"></span>
          </span>
        </div>
        <div class="remove__sub__dir" data-index="${index}">
          <img src="./image/remove.png" class="remove__sub__dir__icon"/>
        </div>
      </div>
      <div class="page__selector">
        <span class="setup__label">页面容器</span>
        <div class="setup__input__wrapper">
          <textarea class="form__textarea" placeholder="页面容器XPath" data-index="${index}" name="xpath" rows="3"></textarea>
        </div>
      </div>
    </div>
  `
}

function toggleSettingPanpelStatus(e) {
  let timer = setTimeout(() => {
    $('.popup__setting__panpel')[0].classList.toggle("popup__setting__panpel__is__show")
    clearTimeout(timer)
  }, 50)
}

function saveSetup() {
  axios({
    url: "http://127.0.0.1:3000/saveSetup",
    method: "POST",
    data: {
      ...setup
    }
  }).then(result => {
    console.log(result);
    renderImageGroup();
  }).catch((err) => {
    
  })
}

/**
 * 渲染图片分组
 */
function renderImageGroup() {
  let imageGroup = ``
  setup.subDirs.filter(item => item.dirname.trim()).forEach((item, index) => {
    imageGroup += `
      <header>${item.dirname}</header>
      <ul class="image__list"></ul>
    `
  })
  $(".image__wrapper").html($(imageGroup))
}

function update() {
  const dirRootPreview = $('.setup__form__item .form__input[name=dirRootPath]').next('.path_preview').find('.dirpath')
  dirRootPreview.html(setup.dirRootPath + '/');

  const rootPreview = $('.setup__form__item .form__input[name=root]').next('.path_preview').find('.dirpath')
  rootPreview.html(setup.dirRootPath + '/' + setup.root + '/');

  const dirnames = $('.sub__dirs .form__input')

  dirnames.each((i, el) => {
    $(el).next('.path_preview').find('.dirpath').html(setup.dirRootPath + '/' + setup.root + '/' + setup.subDirs[i].dirname)
  })

  $('.setup__form__item .form__input').each((i, el) => {
    const name = el.getAttribute('name');
    el.value = setup[name]
  })

  $('.sub__dirs .form__input').each((i, el) => {
    el.value = setup.subDirs[i].dirname
  })

  $('.sub__dirs .form__textarea').each((i, el) => {
    el.value = setup.subDirs[i].xpath
  })
}

function getImages() {
  chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {
      action: 'getImages',
      params: {
        subDirs: setup.subDirs.length ? setup.subDirs : [{
          dirname: "全部",
          xpath: "body"
        }]
      }
    }, function (response) {
      console.log(response);
      if (response) {
        const {
          images = {},
          webUrl = ''
        } = response;

        for (const key in images) {
          if (Object.hasOwnProperty.call(images, key)) {
            const list = images[key];
            images[key] = list.map(item => {
              return {
                ...item,
                isSelected: true
              }
            })
          }
        }

        params = {
          images,
          webUrl,
        }
  
        imageList = deepClone(images)
        
        showImages(images)
      }
    })
  });
}

function showImages(images) {
  $(".image__wrapper").off('click', selectImageHandle)

  const keys = Object.keys(images)
  let imagesHtml = ``
  keys.forEach(key => {
    console.dir();
    const ul = $(`<ul class="image__list"></ul>`);
    ul.append(createImageElement(images[key]))
    imagesHtml += `
      <header>${key}</header>
      <ul class="image__list">
        ${ul.html()}
      </ul>
    `
  })

  $('.image__wrapper').html(imagesHtml)
  
  $(".image__wrapper").on('click', selectImageHandle)
}

function selectImageHandle(event) {
  const li = toggleSelectedStatus(event.target, 'image__item');

  if (!li) return;

  const { id } = li.dataset;

  const keys = Object.keys(imageList)

  outer:for (let i = 0; i < keys.length; i++) {
    const images = imageList[keys[i]];

    for (let j = 0; j < images.length; j++) {
      const item = images[j];
      
      if (item.id === id) {

        if (!li.className.includes("is__selected")) {
          params.images[keys[i]][j].isSelected = false
        } else {
          params.images[keys[i]][j].isSelected = true
        }

        break outer;
      }
    }
  }

  console.log(params.images);
}

function toggleSelectedStatus(eventTarget, parentClassName, toggleClassName = 'is__selected') {
  let parent = parentNode(eventTarget, parentClassName)
    
  if (parent) {
    parent.classList.toggle(toggleClassName)
    return parent;
  };

  return null;
}

function parentNode(target, parentClassName) {
  while (target) {
    if (target.className.split(" ").includes(parentClassName)) {
      return target;
    } else {
      target = target.parentNode
    }
  }

  return null
}

function createImageElement(images) {
  const fragment = document.createDocumentFragment()
  console.log(images);
  images.forEach(image => {
    const li = document.createElement('li')
    li.classList.add('image__item', 'is__selected')
    li.dataset['id'] = image.id;

    // const img = document.createElement('img');
    // img.src = image.src;
    // img.classList.add('gallery__image')

    const isVideo = image.src.endsWith('.mp4')
    let media = `<img src="${image.src}" class="gallery__image" />`

    if (isVideo) {
      media = `<video src="${image.src}" class="gallery__image" poster autoplay="true" muted="muted" type="video/mp4"></video>`
    }
    li.innerHTML = `
      <div class="image__select__icon"></div>
      ${media}
    `

    fragment.append(li)
  });

  return fragment;
}


function generateZIPFile(images) {
  const zip = new JSZip()

  Promise.all(images.map((image, index) => {
    return fetch(image.src)
      .then(result => result.blob())
      .then(blob => {
        let number = index + 1;
        if (number < 10) number = `0${number}`;
      zip.file(number + '-' + url.substring(url.lastIndexOf('/') + 1), blob)
    })
  })).then(() => {
    zip.generateAsync({ type: 'blob' }).then(content => {
      console.log(chrome);
      chrome.downloads.download({
        filename: 'images.zip',
        saveAs: true,
        url: URL.createObjectURL(content)
      }, (e) => {
        console.log(e);
      })
    })
  })
}


function getObjType(obj) {
  let toString = Object.prototype.toString;
  let map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  };
  if (obj instanceof Element) {
    return 'element';
  }
  return map[toString.call(obj)];
};

/**
 * 对象深拷贝
 */
function deepClone(data) {
  let type = getObjType(data);
  let obj;
  if (type === 'array') {
    obj = [];
  } else if (type === 'object') {
    obj = {};
  } else {
    //不再具有下一层次
    return data;
  }
  if (type === 'array') {
    for (let i = 0, len = data.length; i < len; i++) {
      obj.push(deepClone(data[i]));
    }
  } else if (type === 'object') {
    for (let key in data) {
      obj[key] = deepClone(data[key]);
    }
  }
  return obj;
};